/**
 * Token Management Panel UI
 */

export function getTokenPanelHTML() {
  return `<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Anthropic Proxy - Token Management</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <style>
        [x-cloak] { display: none !important; }
        .token-card {
            transition: all 0.3s ease;
        }
        .token-card.active {
            border-color: #10b981;
            box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);
        }
        .spinner {
            animation: spin 1s linear infinite;
        }
        @keyframes spin {
            from { transform: rotate(0deg); }
            to { transform: rotate(360deg); }
        }
    </style>
</head>
<body class="bg-gray-100">
    <div x-data="tokenManager()" x-init="init()" x-cloak>
        <!-- Header -->
        <div class="bg-white shadow-sm border-b">
            <div class="container mx-auto px-4 py-4">
                <div class="flex justify-between items-center">
                    <div class="flex items-center space-x-4">
                        <h1 class="text-2xl font-bold text-gray-800">🔑 Token Management</h1>
                        <a href="/monitor" class="text-blue-500 hover:text-blue-700 flex items-center gap-1">
                            <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"></path>
                            </svg>
                            Back to Monitor
                        </a>
                    </div>
                    <div class="flex gap-2">
                        <button @click="showAddTokenModal()" 
                                class="px-4 py-2 bg-purple-500 text-white rounded hover:bg-purple-600 flex items-center gap-2">
                            <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"></path>
                            </svg>
                            Add Token
                        </button>
                        <button @click="showBulkAddModal()" 
                                class="px-4 py-2 bg-indigo-500 text-white rounded hover:bg-indigo-600 flex items-center gap-2">
                            <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"></path>
                            </svg>
                            Bulk Add
                        </button>
                        <button @click="refreshAllTokens()" 
                                :disabled="isRefreshing"
                                class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 disabled:bg-gray-400 flex items-center gap-2">
                            <svg class="w-4 h-4" :class="{ 'spinner': isRefreshing }" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path>
                            </svg>
                            Refresh All
                        </button>
                        <button @click="reloadTokens()" class="px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600 flex items-center gap-2">
                            <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M9 19l3 3m0 0l3-3m-3 3V10"></path>
                            </svg>
                            Reload from File
                        </button>
                    </div>
                </div>
            </div>
        </div>

        <!-- Alert Messages -->
        <div x-show="alertMessage" x-transition
             class="container mx-auto px-4 mt-4">
            <div :class="{
                'bg-green-100 border-green-400 text-green-700': alertType === 'success',
                'bg-red-100 border-red-400 text-red-700': alertType === 'error',
                'bg-blue-100 border-blue-400 text-blue-700': alertType === 'info'
             }" class="border px-4 py-3 rounded relative" role="alert">
                <span x-text="alertMessage"></span>
                <button @click="alertMessage = ''" class="absolute top-0 bottom-0 right-0 px-4 py-3">
                    <svg class="fill-current h-6 w-6" role="button" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
                        <path d="M14.348 14.849a1.2 1.2 0 0 1-1.697 0L10 11.819l-2.651 3.029a1.2 1.2 0 1 1-1.697-1.697l2.758-3.15-2.759-3.152a1.2 1.2 0 1 1 1.697-1.697L10 8.183l2.651-3.031a1.2 1.2 0 1 1 1.697 1.697l-2.758 3.152 2.758 3.15a1.2 1.2 0 0 1 0 1.698z"/>
                    </svg>
                </button>
            </div>
        </div>

        <!-- Token Stats Summary -->
        <div class="container mx-auto px-4 py-6">
            <div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-6">
                <div class="bg-white rounded-lg shadow p-4">
                    <div class="text-sm text-gray-600">Total Tokens</div>
                    <div class="text-2xl font-bold" x-text="tokens.length"></div>
                </div>
                <div class="bg-white rounded-lg shadow p-4">
                    <div class="text-sm text-gray-600">Active Token</div>
                    <div class="text-2xl font-bold text-green-600" x-text="activeTokenIndex + 1"></div>
                </div>
                <div class="bg-white rounded-lg shadow p-4">
                    <div class="text-sm text-gray-600">Valid Tokens</div>
                    <div class="text-2xl font-bold text-blue-600" x-text="validTokenCount"></div>
                </div>
                <div class="bg-white rounded-lg shadow p-4">
                    <div class="text-sm text-gray-600">Expired Tokens</div>
                    <div class="text-2xl font-bold text-red-600" x-text="expiredTokenCount"></div>
                </div>
            </div>

            <!-- Token List -->
            <div class="space-y-4">
                <template x-for="(token, index) in tokens" :key="index">
                    <div :class="{
                        'active': token.active,
                        'opacity-75': token.isExpired
                    }" class="token-card bg-white rounded-lg shadow-md p-6 border-2 border-gray-200">
                        <div class="flex justify-between items-start">
                            <!-- Token Info -->
                            <div class="flex-1">
                                <div class="flex items-center gap-3 mb-3">
                                    <span class="text-lg font-semibold">Token #<span x-text="index + 1"></span></span>
                                    <span x-show="token.active" class="px-2 py-1 bg-green-100 text-green-800 text-xs font-medium rounded-full">ACTIVE</span>
                                    <span x-show="token.isExpired" class="px-2 py-1 bg-red-100 text-red-800 text-xs font-medium rounded-full">EXPIRED</span>
                                    <span x-show="!token.isExpired && token.needsRefresh" class="px-2 py-1 bg-yellow-100 text-yellow-800 text-xs font-medium rounded-full">NEEDS REFRESH</span>
                                    <span x-show="!token.isExpired && !token.needsRefresh" class="px-2 py-1 bg-blue-100 text-blue-800 text-xs font-medium rounded-full">VALID</span>
                                </div>

                                <div class="grid grid-cols-2 md:grid-cols-3 gap-4 text-sm">
                                    <div>
                                        <span class="text-gray-600">Name:</span>
                                        <span class="font-medium" x-text="token.name || 'Unknown'"></span>
                                    </div>
                                    <div>
                                        <span class="text-gray-600">Subscription:</span>
                                        <span class="font-medium capitalize" x-text="token.subscriptionType"></span>
                                    </div>
                                    <div>
                                        <span class="text-gray-600">Scopes:</span>
                                        <span class="font-mono text-xs" x-text="token.scopes?.join(', ') || 'N/A'"></span>
                                    </div>
                                    <div class="col-span-2">
                                        <span class="text-gray-600">Access Token:</span>
                                        <span class="font-mono text-xs" x-text="maskToken(token.accessToken)"></span>
                                    </div>
                                    <div>
                                        <span class="text-gray-600">Expires At:</span>
                                        <span class="font-medium" :class="{
                                            'text-red-600': token.isExpired,
                                            'text-yellow-600': token.needsRefresh && !token.isExpired,
                                            'text-green-600': !token.needsRefresh && !token.isExpired
                                        }" x-text="formatDateTime(token.expiresAt)"></span>
                                    </div>
                                    <div>
                                        <span class="text-gray-600">Time Remaining:</span>
                                        <span class="font-medium" :class="{
                                            'text-red-600': token.isExpired,
                                            'text-yellow-600': token.expiresInMinutes < 30 && !token.isExpired,
                                            'text-green-600': token.expiresInMinutes >= 30
                                        }" x-text="formatTimeRemaining(token.expiresInMinutes)"></span>
                                    </div>
                                    <div x-show="token.lastRefreshed">
                                        <span class="text-gray-600">Last Refreshed:</span>
                                        <span class="font-medium" x-text="formatDateTime(token.lastRefreshed)"></span>
                                    </div>
                                    <div x-show="token.refreshCount > 0">
                                        <span class="text-gray-600">Refresh Count:</span>
                                        <span class="font-medium" x-text="token.refreshCount || 0"></span>
                                    </div>
                                </div>

                                <!-- Error Message -->
                                <div x-show="token.error" class="mt-3 p-2 bg-red-50 border border-red-200 rounded text-sm text-red-700">
                                    <span class="font-medium">Error:</span> <span x-text="token.error"></span>
                                </div>
                            </div>

                            <!-- Action Buttons -->
                            <div class="flex flex-col gap-2 ml-4">
                                <button @click="activateToken(index)" 
                                        :disabled="token.active || token.isExpired || isRefreshing"
                                        class="px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600 disabled:bg-gray-400 disabled:cursor-not-allowed flex items-center gap-2">
                                    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
                                    </svg>
                                    <span x-text="token.active ? 'Active' : 'Activate'"></span>
                                </button>
                                
                                <button @click="refreshToken(index)" 
                                        :disabled="isRefreshing"
                                        class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 disabled:bg-gray-400 flex items-center gap-2">
                                    <svg class="w-4 h-4" :class="{ 'spinner': refreshingTokens[index] }" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path>
                                    </svg>
                                    Refresh
                                </button>

                                <button @click="copyToken(token.accessToken)" 
                                        class="px-4 py-2 bg-gray-500 text-white rounded hover:bg-gray-600 flex items-center gap-2">
                                    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"></path>
                                    </svg>
                                    Copy
                                </button>
                                
                                <button @click="confirmDeleteToken(index, token.name)" 
                                        class="px-4 py-2 bg-red-500 text-white rounded hover:bg-red-600 flex items-center gap-2">
                                    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path>
                                    </svg>
                                    Delete
                                </button>
                            </div>
                        </div>
                    </div>
                </template>
            </div>

            <!-- No Tokens Message -->
            <div x-show="tokens.length === 0" class="bg-white rounded-lg shadow p-8 text-center">
                <svg class="mx-auto h-12 w-12 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"></path>
                </svg>
                <h3 class="mt-2 text-sm font-medium text-gray-900">No tokens configured</h3>
                <p class="mt-1 text-sm text-gray-500">Please configure OAuth tokens in the .authtoken file</p>
            </div>
        </div>

        <!-- Add Token Modal -->
        <div x-show="showAddModal" 
             x-transition:enter="transition ease-out duration-300"
             x-transition:enter-start="opacity-0"
             x-transition:enter-end="opacity-100"
             x-transition:leave="transition ease-in duration-200"
             x-transition:leave-start="opacity-100"
             x-transition:leave-end="opacity-0"
             class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
             @click.self="showAddModal = false">
            <div class="bg-white rounded-lg p-6 max-w-2xl w-full max-h-[80vh] overflow-y-auto">
                <h3 class="text-lg font-bold mb-4">Add New Token</h3>
                <div class="space-y-4">
                    <div>
                        <label class="block text-sm font-medium text-gray-700">Name (optional)</label>
                        <input x-model="newTokenName" type="text" placeholder="User name" 
                               class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm p-2 border">
                    </div>
                    <div>
                        <label class="block text-sm font-medium text-gray-700">Token JSON</label>
                        <textarea x-model="newTokenData" 
                                  placeholder='Paste JSON format token here, e.g.:\n{"claudeAiOauth": {"accessToken": "sk-ant-oat01-xxx", "refreshToken": "sk-ant-ort01-xxx", ...}}'
                                  rows="8"
                                  class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm p-2 border font-mono text-xs"></textarea>
                    </div>
                    <div class="text-xs text-gray-500">
                        Expected format: {"claudeAiOauth": {"accessToken": "...", "refreshToken": "...", "expiresAt": ..., "scopes": [...], "subscriptionType": "..."}}
                    </div>
                </div>
                <div class="mt-6 flex gap-2 justify-end">
                    <button @click="showAddModal = false" class="px-4 py-2 bg-gray-300 text-gray-700 rounded hover:bg-gray-400">
                        Cancel
                    </button>
                    <button @click="addToken()" class="px-4 py-2 bg-purple-500 text-white rounded hover:bg-purple-600">
                        Add Token
                    </button>
                </div>
            </div>
        </div>

        <!-- Bulk Add Modal -->
        <div x-show="showBulkModal" 
             x-transition:enter="transition ease-out duration-300"
             x-transition:enter-start="opacity-0"
             x-transition:enter-end="opacity-100"
             x-transition:leave="transition ease-in duration-200"
             x-transition:leave-start="opacity-100"
             x-transition:leave-end="opacity-0"
             class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
             @click.self="showBulkModal = false">
            <div class="bg-white rounded-lg p-6 max-w-2xl w-full max-h-[80vh] overflow-y-auto">
                <h3 class="text-lg font-bold mb-4">Bulk Add Tokens</h3>
                <div class="space-y-4">
                    <div>
                        <label class="block text-sm font-medium text-gray-700">Token Array JSON</label>
                        <textarea x-model="bulkTokenData" 
                                  placeholder='Paste JSON array of tokens here, e.g.:\n[\n  {"name": "User1", "claudeAiOauth": {...}},\n  {"name": "User2", "claudeAiOauth": {...}}\n]'
                                  rows="12"
                                  class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm p-2 border font-mono text-xs"></textarea>
                    </div>
                    <div class="text-xs text-gray-500">
                        Expected format: Array of token objects, each with optional "name" and required "claudeAiOauth" fields
                    </div>
                </div>
                <div class="mt-6 flex gap-2 justify-end">
                    <button @click="showBulkModal = false" class="px-4 py-2 bg-gray-300 text-gray-700 rounded hover:bg-gray-400">
                        Cancel
                    </button>
                    <button @click="bulkAddTokens()" class="px-4 py-2 bg-indigo-500 text-white rounded hover:bg-indigo-600">
                        Add All Tokens
                    </button>
                </div>
            </div>
        </div>

        <!-- Duplicate Confirmation Modal -->
        <div x-show="showDuplicateModal" 
             x-transition:enter="transition ease-out duration-300"
             x-transition:enter-start="opacity-0"
             x-transition:enter-end="opacity-100"
             x-transition:leave="transition ease-in duration-200"
             x-transition:leave-start="opacity-100"
             x-transition:leave-end="opacity-0"
             class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
             @click.self="showDuplicateModal = false">
            <div class="bg-white rounded-lg p-6 max-w-md w-full">
                <h3 class="text-lg font-bold mb-4 text-yellow-600">⚠️ Duplicate Detected</h3>
                <div class="text-gray-700 mb-6">
                    <p x-show="duplicateInfo.duplicateName" class="mb-2">
                        <strong>Name already exists:</strong> "<span x-text="duplicateInfo.existingName"></span>"
                    </p>
                    <p x-show="duplicateInfo.duplicateToken" class="mb-2">
                        <strong>Token already exists</strong> at index <span x-text="(duplicateInfo.tokenIndex + 1)"></span>
                    </p>
                    <p class="mt-4 font-semibold">Do you want to overwrite the existing entry?</p>
                </div>
                <div class="mt-6 flex gap-2 justify-end">
                    <button @click="showDuplicateModal = false" class="px-4 py-2 bg-gray-300 text-gray-700 rounded hover:bg-gray-400">
                        Cancel
                    </button>
                    <button @click="confirmAddWithOverwrite()" class="px-4 py-2 bg-yellow-500 text-white rounded hover:bg-yellow-600">
                        Overwrite
                    </button>
                </div>
            </div>
        </div>

        <!-- Delete Confirmation Modal -->
        <div x-show="showDeleteModal" 
             x-transition:enter="transition ease-out duration-300"
             x-transition:enter-start="opacity-0"
             x-transition:enter-end="opacity-100"
             x-transition:leave="transition ease-in duration-200"
             x-transition:leave-start="opacity-100"
             x-transition:leave-end="opacity-0"
             class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
             @click.self="showDeleteModal = false">
            <div class="bg-white rounded-lg p-6 max-w-md w-full">
                <h3 class="text-lg font-bold mb-4">Confirm Delete</h3>
                <p class="text-gray-700 mb-6">
                    Are you sure you want to delete token "<span x-text="deleteTokenName"></span>" (Index: <span x-text="deleteTokenIndex + 1"></span>)?
                </p>
                <div class="flex gap-2 justify-end">
                    <button @click="showDeleteModal = false" class="px-4 py-2 bg-gray-300 text-gray-700 rounded hover:bg-gray-400">
                        Cancel
                    </button>
                    <button @click="deleteToken()" class="px-4 py-2 bg-red-500 text-white rounded hover:bg-red-600">
                        Delete
                    </button>
                </div>
            </div>
        </div>
    </div>

    <script>
        // Define the tokenManager component before Alpine loads
        function tokenManager() {
            return {
                tokens: [],
                activeTokenIndex: -1,
                isRefreshing: false,
                refreshingTokens: {},
                alertMessage: '',
                alertType: 'info',
                refreshInterval: null,
                validTokenCount: 0,
                expiredTokenCount: 0,
                showAddModal: false,
                showBulkModal: false,
                showDeleteModal: false,
                showDuplicateModal: false,
                duplicateInfo: {},
                pendingTokenData: null,
                pendingTokenName: null,
                newTokenName: '',
                newTokenData: '',
                bulkTokenData: '',
                deleteTokenIndex: null,
                deleteTokenName: '',

                async init() {
                    console.log('Token Manager initializing...');
                    await this.loadTokens();
                    // Auto refresh every 30 seconds
                    this.refreshInterval = setInterval(() => this.loadTokens(true), 30000);
                },

                async loadTokens(silent = false) {
                    try {
                        console.log('Loading tokens from /api/oauth/status...');
                        const response = await fetch('/api/oauth/status');
                        const data = await response.json();
                        console.log('Received data:', data);
                        
                        if (data.configured) {
                            this.tokens = data.allTokens || [];
                            this.activeTokenIndex = data.currentTokenIndex || 0;
                            console.log('Loaded ' + this.tokens.length + ' tokens');
                            
                            // Calculate stats
                            this.validTokenCount = this.tokens.filter(t => !t.isExpired).length;
                            this.expiredTokenCount = this.tokens.filter(t => t.isExpired).length;
                            
                            if (!silent) {
                                this.showAlert('Tokens loaded successfully', 'success');
                            }
                        } else {
                            this.tokens = [];
                            console.log('OAuth not configured');
                            if (!silent) {
                                this.showAlert('OAuth is not configured', 'error');
                            }
                        }
                    } catch (error) {
                        console.error('Failed to load tokens:', error);
                        if (!silent) {
                            this.showAlert('Failed to load tokens: ' + error.message, 'error');
                        }
                    }
                },

                async activateToken(index) {
                    if (this.isRefreshing) return;
                    
                    try {
                        this.isRefreshing = true;
                        const response = await fetch(\`/api/oauth/switch/\${index}\`, {
                            method: 'POST'
                        });
                        
                        const data = await response.json();
                        
                        if (response.ok && data.success) {
                            this.showAlert(\`Switched to token #\${index + 1}\`, 'success');
                            await this.loadTokens(true);
                        } else {
                            this.showAlert(data.error || 'Failed to switch token', 'error');
                        }
                    } catch (error) {
                        console.error('Failed to activate token:', error);
                        this.showAlert('Failed to activate token: ' + error.message, 'error');
                    } finally {
                        this.isRefreshing = false;
                    }
                },

                async refreshToken(index) {
                    if (this.isRefreshing) return;
                    
                    try {
                        this.refreshingTokens[index] = true;
                        this.isRefreshing = true;
                        
                        // First switch to the token
                        await fetch(\`/api/oauth/switch/\${index}\`, { method: 'POST' });
                        
                        // Then refresh it
                        const response = await fetch('/api/oauth/refresh');
                        const data = await response.json();
                        
                        if (response.ok && data.success) {
                            this.showAlert(\`Token #\${index + 1} refreshed successfully\`, 'success');
                            await this.loadTokens(true);
                        } else {
                            this.showAlert(data.error || \`Failed to refresh token #\${index + 1}\`, 'error');
                        }
                    } catch (error) {
                        console.error('Failed to refresh token:', error);
                        this.showAlert('Failed to refresh token: ' + error.message, 'error');
                    } finally {
                        this.refreshingTokens[index] = false;
                        this.isRefreshing = false;
                    }
                },

                async refreshAllTokens() {
                    if (this.isRefreshing) return;
                    
                    try {
                        this.isRefreshing = true;
                        const response = await fetch('/api/oauth/refresh/all', {
                            method: 'POST'
                        });
                        
                        const data = await response.json();
                        
                        if (response.ok && data.success) {
                            this.showAlert('All tokens refreshed successfully', 'success');
                            await this.loadTokens(true);
                        } else {
                            this.showAlert(data.error || 'Some tokens failed to refresh', 'error');
                        }
                    } catch (error) {
                        console.error('Failed to refresh all tokens:', error);
                        this.showAlert('Failed to refresh all tokens: ' + error.message, 'error');
                    } finally {
                        this.isRefreshing = false;
                    }
                },

                async reloadTokens() {
                    try {
                        this.isRefreshing = true;
                        const response = await fetch('/api/oauth/reload', {
                            method: 'POST'
                        });
                        
                        const data = await response.json();
                        
                        if (response.ok && data.success) {
                            this.showAlert(\`Reloaded \${data.currentTokenCount} tokens from file\`, 'success');
                            await this.loadTokens(true);
                        } else {
                            this.showAlert(data.error || 'Failed to reload tokens', 'error');
                        }
                    } catch (error) {
                        console.error('Failed to reload tokens:', error);
                        this.showAlert('Failed to reload tokens: ' + error.message, 'error');
                    } finally {
                        this.isRefreshing = false;
                    }
                },

                maskToken(token) {
                    if (!token) return 'N/A';
                    if (token.length <= 20) return token;
                    return token.substring(0, 10) + '...' + token.substring(token.length - 10);
                },

                formatDateTime(dateStr) {
                    if (!dateStr) return 'N/A';
                    const date = new Date(dateStr);
                    return date.toLocaleString();
                },

                formatTimeRemaining(minutes) {
                    if (minutes === undefined || minutes === null) return 'N/A';
                    
                    if (minutes < 0) {
                        const absMinutes = Math.abs(minutes);
                        if (absMinutes < 60) return \`Expired \${absMinutes} min ago\`;
                        if (absMinutes < 1440) return \`Expired \${Math.floor(absMinutes / 60)} hours ago\`;
                        return \`Expired \${Math.floor(absMinutes / 1440)} days ago\`;
                    }
                    
                    if (minutes < 60) return \`\${minutes} minutes\`;
                    if (minutes < 1440) return \`\${Math.floor(minutes / 60)} hours\`;
                    return \`\${Math.floor(minutes / 1440)} days\`;
                },

                async copyToken(token) {
                    try {
                        await navigator.clipboard.writeText(token);
                        this.showAlert('Token copied to clipboard', 'success');
                    } catch (err) {
                        // Fallback for older browsers
                        const textarea = document.createElement('textarea');
                        textarea.value = token;
                        document.body.appendChild(textarea);
                        textarea.select();
                        try {
                            document.execCommand('copy');
                            this.showAlert('Token copied to clipboard', 'success');
                        } catch (err) {
                            this.showAlert('Failed to copy token', 'error');
                        }
                        document.body.removeChild(textarea);
                    }
                },

                showAlert(message, type = 'info') {
                    this.alertMessage = message;
                    this.alertType = type;
                    setTimeout(() => {
                        this.alertMessage = '';
                    }, 5000);
                },

                showAddTokenModal() {
                    this.newTokenName = '';
                    this.newTokenData = '';
                    this.showAddModal = true;
                },

                showBulkAddModal() {
                    this.bulkTokenData = '';
                    this.showBulkModal = true;
                },

                async addToken(force = false) {
                    try {
                        if (!this.newTokenData) {
                            this.showAlert('Please enter token data', 'error');
                            return;
                        }

                        const response = await fetch('/api/oauth/tokens', {
                            method: 'POST',
                            headers: { 'Content-Type': 'application/json' },
                            body: JSON.stringify({
                                token: this.newTokenData,
                                name: this.newTokenName,
                                force: force
                            })
                        });
                        
                        const data = await response.json();
                        
                        // Handle duplicate detection
                        if (response.status === 409 && data.duplicate) {
                            this.duplicateInfo = data;
                            this.pendingTokenData = this.newTokenData;
                            this.pendingTokenName = this.newTokenName;
                            this.showDuplicateModal = true;
                            return;
                        }
                        
                        if (data.success) {
                            const action = data.overwritten ? 'overwritten' : 'added';
                            this.showAlert(\`Token "\${data.name}" \${action} successfully at index \${data.index + 1}\`, 'success');
                            this.showAddModal = false;
                            this.showDuplicateModal = false;
                            await this.loadTokens(true);
                        } else {
                            this.showAlert('Failed to add token: ' + (data.error || 'Unknown error'), 'error');
                        }
                    } catch (error) {
                        this.showAlert('Error adding token: ' + error.message, 'error');
                    }
                },

                async confirmAddWithOverwrite() {
                    // Restore the pending data and force add
                    this.newTokenData = this.pendingTokenData;
                    this.newTokenName = this.pendingTokenName;
                    await this.addToken(true);
                },

                async bulkAddTokens() {
                    try {
                        if (!this.bulkTokenData) {
                            this.showAlert('Please enter token array data', 'error');
                            return;
                        }

                        const response = await fetch('/api/oauth/tokens/bulk', {
                            method: 'POST',
                            headers: { 'Content-Type': 'application/json' },
                            body: JSON.stringify({
                                tokens: this.bulkTokenData
                            })
                        });
                        
                        const data = await response.json();
                        
                        if (data.success) {
                            this.showAlert(\`\${data.added} tokens added successfully\`, 'success');
                            this.showBulkModal = false;
                            await this.loadTokens(true);
                        } else {
                            this.showAlert('Failed to add tokens: ' + data.error, 'error');
                        }
                    } catch (error) {
                        this.showAlert('Error adding tokens: ' + error.message, 'error');
                    }
                },

                confirmDeleteToken(index, name) {
                    this.deleteTokenIndex = index;
                    this.deleteTokenName = name;
                    this.showDeleteModal = true;
                },

                async deleteToken() {
                    try {
                        const response = await fetch(\`/api/oauth/tokens/\${this.deleteTokenIndex}\`, {
                            method: 'DELETE',
                            headers: { 'Content-Type': 'application/json' }
                        });
                        
                        const data = await response.json();
                        
                        if (data.success) {
                            this.showAlert(\`Token "\${data.deletedName}" deleted successfully\`, 'success');
                            this.showDeleteModal = false;
                            await this.loadTokens(true);
                        } else {
                            this.showAlert('Failed to delete token: ' + data.error, 'error');
                        }
                    } catch (error) {
                        this.showAlert('Error deleting token: ' + error.message, 'error');
                    }
                }
            };
        }
    </script>
    <script src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js" defer></script>
</body>
</html>`;
}